import 'dart:math';

import 'package:bxultimate/app/router/router_name.dart';
import 'package:bxultimate/app/theme/app_theme.dart';
import 'package:bxultimate/app/theme/gaps.dart';
import 'package:bxultimate/data/request/organization_request.dart';
import 'package:bxultimate/domain/application/organization/chat_model.dart';
import 'package:bxultimate/resources/assets.dart';
import 'package:bxultimate/widgets/chat/chat_item_widget.dart';
import 'package:bxultimate/widgets/chat/chat_unread_tip_view.dart';
import 'package:bxultimate/widgets/mk_load_image.dart';
import 'package:bxultimate/widgets/mk_page.dart';
import 'package:easy_refresh/easy_refresh.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:scrollview_observer/scrollview_observer.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';

import 'controller.dart';

class OrganizationChatPage extends StatefulWidget {
  const OrganizationChatPage({Key? key}) : super(key: key);

  @override
  State<OrganizationChatPage> createState() => _OrganizationChatPageState();
}

class _OrganizationChatPageState extends State<OrganizationChatPage>
    with WidgetsBindingObserver {
  final controller = Get.find<OrganizationChatController>();
  final state = Get.find<OrganizationChatController>().state;

  ScrollController scrollController = ScrollController();

  late ListObserverController observerController;

  late ChatScrollObserver chatObserver;

  List<ChatModel> chatModels = [];

  ValueNotifier<int> unreadMsgCount = ValueNotifier<int>(0);

  bool needIncrementUnreadMsgCount = false;

  bool editViewReadOnly = false;

  TextEditingController editViewController = TextEditingController();

  BuildContext? pageOverlayContext;

  final LayerLink layerLink = LayerLink();

  bool isShowClassicHeaderAndFooter = true;

  var chatList = [];

  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addObserver(this);

    // chatModels = createChatModels();

    getRecords();

    scrollController.addListener(scrollControllerListener);

    observerController = ListObserverController(controller: scrollController)
      ..cacheJumpIndexOffset = false;

    chatObserver = ChatScrollObserver(observerController)
      ..fixedPositionOffset = 5
      ..toRebuildScrollViewCallback = () {
        setState(() {});
      }
      ..onHandlePositionResultCallback = (result) {
        if (!needIncrementUnreadMsgCount) return;
        switch (result.type) {
          case ChatScrollObserverHandlePositionType.keepPosition:
            updateUnreadMsgCount(changeCount: result.changeCount);
            break;
          case ChatScrollObserverHandlePositionType.none:
            updateUnreadMsgCount(isReset: true);
            break;
        }
      };

    Future.delayed(const Duration(seconds: 1), addUnreadTipView);
  }

  @override
  void didChangeMetrics() {
    super.didChangeMetrics();
    // Update shrinkWrap in real time as the keyboard pops up or closes.
    chatObserver.observeSwitchShrinkWrap();

    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (mounted) {
        if (MediaQuery.of(context).viewInsets.bottom == 0) {
          // Keyboard closes
        } else {
          // Keyboard pops up
          scrollController.jumpTo(0);
        }
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return MkPage(
      child: Obx(() => Scaffold(
            backgroundColor: Colors.transparent,
            appBar: TDNavBar(
              title: '${state.chatRoomInfo.teamName}',
              backgroundColor: Colors.transparent,
              rightBarItems: [
                TDNavBarItem(
                  action: controller.toOrganizationInformationPage,
                  iconWidget: const Icon(Icons.info_outline),
                )
              ],
            ),
            body: _buildBody(),
          )),
    );
  }

  Widget _buildPageOverlay() {
    return Overlay(initialEntries: [
      OverlayEntry(
        builder: (context) {
          pageOverlayContext = context;
          return Container();
        },
      )
    ]);
  }

  Widget _buildBody() {
    Widget resultWidget = _buildListView();
    // Dismiss keyboard when clicking or dragging ScrollView.
    resultWidget = GestureDetector(
      behavior: HitTestBehavior.translucent,
      onTap: () {
        KeyboardTool.dismissKeyboard(context);
      },
      onPanDown: (_) {
        KeyboardTool.dismissKeyboard(context);
      },
      child: resultWidget,
    );
    resultWidget = Column(
      children: [
        Expanded(child: resultWidget),
        CompositedTransformTarget(
          link: layerLink,
          child: Container(),
        ),
        _buildEditView(),
      ],
    );
    resultWidget = Stack(children: [
      resultWidget,
      _buildPageOverlay(),
    ]);
    return resultWidget;
  }

  Widget _buildEditView() {
    return Container(
        margin: const EdgeInsets.symmetric(horizontal: 4, vertical: 4),
        decoration: BoxDecoration(color: Colors.white
            // color: Colors.white,
            ),
        child: SafeArea(
          child: Column(
            children: [
              Obx(() => GestureDetector(
                    onTapDown: (_) {
                      controller.say();
                    },
                    onTapUp: (_) {
                      controller.sayCancel();
                    },
                    onTapCancel: () {
                      controller.sayCancel();
                    },
                    child: Container(
                      margin: EdgeInsets.only(
                          left: AppTheme.iDefaultPadding,
                          right: AppTheme.iDefaultPadding,
                          top: AppTheme.iDefaultPadding),
                      padding: EdgeInsets.all(AppTheme.iDefaultPadding / 2),
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(20),
                        border:
                            Border.all(color: AppTheme.primaryColor, width: 2),
                      ),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          MkLoadImage(
                            Assets.organizationSpeak,
                            width: 24,
                          ),
                          Gaps.hGap12,
                          Text(
                            '${state.sayText}',
                            style: TextStyle(
                                color: AppTheme.primaryColor,
                                fontWeight: FontWeight.bold),
                          )
                        ],
                      ),
                    ),
                  )),
              Container(
                width: Get.width,
                decoration: BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.circular(AppTheme.iDefaultRadius),
                ),
                child: Wrap(
                  alignment: WrapAlignment.start,
                  children: [
                    _buildModuleItem(Assets.organizationApproveIcon, '审批', () {
                      Get.toNamed(RouterName.organizationApprove,
                          arguments: Get.arguments['orgId']);
                    }),
                    _buildModuleItem(Assets.organizationAnalysis, '统计', () {
                      Get.toNamed(RouterName.organizationStatisticsTaskList,
                          arguments: {
                            "id": Get.arguments['orgId'],
                            "chatRoomId": state.chatRoomInfo.id,
                            "sysType": state.chatRoomInfo.sysType,
                            "attributionCode":
                                state.chatRoomInfo.attributionCode,
                            "attributionTargetId":
                                state.chatRoomInfo.attributionTargetId,
                          });
                    }),
                    _buildModuleItem(Assets.organizationPosition, '定位', () {
                      controller.updatePosition();
                    }),
                    _buildModuleItem(Assets.organizationAd, '公告', () {
                      Get.toNamed(RouterName.organizationAnnouncementList,
                          arguments: {
                            "id": state.chatRoomInfo.id,
                            "sysType": state.chatRoomInfo.sysType
                          });
                    }),
                    _buildModuleItem(Assets.organizationAttendance, '考勤', () {
                      Get.toNamed(RouterName.organizationAttendanceManagement,
                          arguments: Get.arguments['orgId']);
                    }),
                    _buildModuleItem(Assets.loginIconWx, '登记', () {
                      Get.toNamed(RouterName.organizationAccessRegList);
                    }),
                  ],
                ),
              )
            ],
          ),
        ));
  }

  _buildModuleItem(icon, name, onTap) {
    return GestureDetector(
      onTap: onTap,
      child: Container(
          width: (Get.width - AppTheme.iDefaultPadding * 2) / 4,
          padding: EdgeInsets.all(AppTheme.iDefaultPadding),
          child: Column(children: [
            MkLoadImage(
              icon,
              width: 30,
              height: 30,
            ),
            Gaps.vGap4,
            Text(
              name,
              style: TextStyle(fontSize: 12),
            )
          ])),
    );
  }

  Widget _buildUnreadTipView() {
    return ValueListenableBuilder<int>(
      builder: (context, value, child) {
        return ChatUnreadTipView(
          unreadMsgCount: unreadMsgCount.value,
          onTap: () {
            scrollController.animateTo(
              0,
              duration: const Duration(milliseconds: 300),
              curve: Curves.easeInOut,
            );
            updateUnreadMsgCount(isReset: true);
          },
        );
      },
      valueListenable: unreadMsgCount,
    );
  }

  Widget _buildListView() {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        Widget resultWidget = EasyRefresh.builder(
          header: isShowClassicHeaderAndFooter
              ? const ClassicHeader()
              : const MaterialHeader(),
          footer: isShowClassicHeaderAndFooter
              ? const ClassicFooter(
                  position: IndicatorPosition.above,
                  infiniteOffset: null,
                )
              : const MaterialFooter(),
          onLoad: () async {
            await Future.delayed(const Duration(seconds: 2));
          },
          childBuilder: (context, physics) {
            var scrollViewPhysics =
                physics.applyTo(ChatObserverClampingScrollPhysics(
              observer: chatObserver,
            ));
            Widget resultWidget = ListView.builder(
              physics: chatObserver.isShrinkWrap
                  ? const NeverScrollableScrollPhysics()
                  : scrollViewPhysics,
              padding: const EdgeInsets.only(
                left: 10,
                right: 10,
                top: 15,
                bottom: 15,
              ),
              shrinkWrap: chatObserver.isShrinkWrap,
              reverse: true,
              controller: scrollController,
              itemBuilder: ((context, index) {
                return ChatItemWidget(
                  chatModel: chatList[index],
                  index: index,
                  itemCount: chatList.length,
                  onRemove: () {
                    chatObserver.standby(isRemove: true);
                    setState(() {
                      chatList.removeAt(index);
                    });
                  },
                );
              }),
              itemCount: chatList.length,
            );
            if (chatObserver.isShrinkWrap) {
              resultWidget = SingleChildScrollView(
                reverse: true,
                physics: scrollViewPhysics,
                child: Container(
                  alignment: Alignment.topCenter,
                  child: resultWidget,
                  height: constraints.maxHeight + 0.001,
                ),
              );
            }
            return resultWidget;
          },
        );

        resultWidget = ListViewObserver(
          controller: observerController,
          child: resultWidget,
        );
        resultWidget = Align(
          child: resultWidget,
          alignment: Alignment.topCenter,
        );
        return resultWidget;
      },
    );
  }

  addUnreadTipView() {
    Overlay.of(pageOverlayContext!).insert(OverlayEntry(
      builder: (BuildContext context) => UnconstrainedBox(
        child: CompositedTransformFollower(
          link: layerLink,
          followerAnchor: Alignment.bottomRight,
          targetAnchor: Alignment.topRight,
          offset: const Offset(-20, 0),
          child: Material(
            type: MaterialType.transparency,
            // color: Colors.green,
            child: _buildUnreadTipView(),
          ),
        ),
      ),
    ));
  }

  List<ChatModel> createChatModels({int num = 20}) {
    return Iterable<int>.generate(num)
        .map((e) => ChatDataHelper.createChatModel())
        .toList();
  }

  getRecords() async {
    state.chatRoomInfo = await OrganizationRequest.getChatRoom(
        Get.arguments["orgId"],
        Get.arguments['attributionCode'],
        Get.arguments['areaLsgx']);

    chatList =
        await OrganizationRequest.getRecordList(1, 10, state.chatRoomInfo.id);
    setState(() {});
    chatObserver.standby();
  }

  _addMessage(int count) {
    chatObserver.standby(changeCount: count);
    setState(() {
      needIncrementUnreadMsgCount = true;
      for (var i = 0; i < count; i++) {
        chatModels.insert(0, ChatDataHelper.createChatModel());
      }
    });
  }

  updateUnreadMsgCount({
    bool isReset = false,
    int changeCount = 1,
  }) {
    needIncrementUnreadMsgCount = false;
    if (isReset) {
      unreadMsgCount.value = 0;
    } else {
      unreadMsgCount.value += changeCount;
    }
  }

  scrollControllerListener() {
    if (scrollController.offset < 50) {
      updateUnreadMsgCount(isReset: true);
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    observerController.controller?.dispose();
    editViewController.dispose();
    Get.delete<OrganizationChatController>();
    super.dispose();
  }
}

class ChatDataHelper {
  static List<String> chatContents = [
    'My name is LinXunFeng',
    'Twitter: https://twitter.com/xunfenghellolo'
        'Github: https://github.com/LinXunFeng',
    'Blog: https://fullstackaction.com/',
    'Juejin: https://juejin.cn/user/1820446984512392/posts',
    'Artile: Flutter-获取ListView当前正在显示的Widget信息\nhttps://juejin.cn/post/7103058155692621837',
    'Artile: Flutter-列表滚动定位超强辅助库，墙裂推荐！🔥\nhttps://juejin.cn/post/7129888644290068487',
    'A widget for observing data related to the child widgets being displayed in a scrollview.\nhttps://github.com/LinXunFeng/flutter_scrollview_observer',
    '📱 Swifty screen adaptation solution (Support Objective-C and Swift)\nhttps://github.com/LinXunFeng/SwiftyFitsize'
  ];

  static ChatModel createChatModel({
    bool? isOwn,
  }) {
    final random = Random();
    final content =
        ChatDataHelper.chatContents[random.nextInt(chatContents.length)];
    return ChatModel(
      isOwn: isOwn ?? random.nextBool(),
      content: content,
    );
  }
}

class KeyboardTool {
  static void dismissKeyboard(BuildContext context) {
    FocusScopeNode currentFocus = FocusScope.of(context);
    if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
      FocusManager.instance.primaryFocus?.unfocus();
    }
  }
}
